#ifndef PUBLIC_H
#define PUBLIC_H

#ifdef __cplusplus
extern "C"
{
#endif

// 公共头文件内容
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#include "config.h"
#include "cmd_def.h"
// 硬件系列宏定义
#if defined(STM32F100xB) || defined(STM32F100xE) || defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
#define SOC_SERIES_STM32F1
#elif defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || defined(STM32F423xx)
#define SOC_SERIES_STM32F4
#else
#error "Please define STM32F1/F4 series macro!"
#endif

// 公共宏定义
#define err_ok (0)
#define err_invalid_obj (-1)   // 无效对象错误
#define err_invalid_param (-2) // 无效参数错误
#define err_not_idle (-3)      // 非空闲状态错误

// 操作类型定义
#ifndef SET_BIT
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#endif

#ifndef CLEAR_BIT
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
#endif

#ifndef READ_BIT
#define READ_BIT(REG, BIT) ((REG) & (BIT))
#endif

#ifndef CLEAR_REG
#define CLEAR_REG(REG) ((REG) = (0x0))
#endif

#ifndef WRITE_REG
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
#endif

#ifndef READ_REG
#define READ_REG(REG) ((REG))
#endif

#ifndef MODIFY_REG
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
#endif

#ifndef POSITION_VAL
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
#endif

/* ------------------------- 原子操作宏 ------------------------- */
/* 编译时类型检查（确保寄存器为8/16/32位） */
// #define __CHECK_REG_SIZE(REG)                                                \
//     _Static_assert(sizeof(REG) == 1 || sizeof(REG) == 2 || sizeof(REG) == 4, \
//                    "Register size must be 8/16/32-bit")
#define __CHECK_REG_SIZE(REG)

/* 根据变量大小生成指针类型 */
#define __ATOMIC_PTR(reg, type) (volatile type *)&(reg)

/* 动态生成原子操作函数名 */
#define __LDREX_IMPL(reg)                                                                                                   \
    (sizeof(reg) == 4) ? __LDREXW(__ATOMIC_PTR(reg, uint32_t)) : (sizeof(reg) == 2) ? __LDREXH(__ATOMIC_PTR(reg, uint16_t)) \
                                                                                    : __LDREXB(__ATOMIC_PTR(reg, uint8_t))

#define __STREX_IMPL(reg, val)                                                                                                            \
    (sizeof(reg) == 4) ? __STREXW((val), __ATOMIC_PTR(reg, uint32_t)) : (sizeof(reg) == 2) ? __STREXH((val), __ATOMIC_PTR(reg, uint16_t)) \
                                                                                           : __STREXB((val), __ATOMIC_PTR(reg, uint8_t))
/* 原子读 */
#define ATOMIC_READ(REG, BIT) ({                                                                                                              \
    __CHECK_REG_SIZE(REG);                                                                                                                    \
    typeof(REG) val = (sizeof(REG) == 4) ? __LDREXW((volatile uint32_t *)&(REG)) : (sizeof(REG) == 2) ? __LDREXH((volatile uint16_t *)&(REG)) \
                                                                                                      : __LDREXB((volatile uint8_t *)&(REG)); \
    __CLREX();                                                                                                                                \
    (val & (BIT));                                                                                                                            \
})

/* 原子置位 */
#define ATOMIC_SET(REG, BIT)                                                                                                                              \
    do                                                                                                                                                    \
    {                                                                                                                                                     \
        __CHECK_REG_SIZE(REG);                                                                                                                            \
        typeof(REG) val;                                                                                                                                  \
        do                                                                                                                                                \
        {                                                                                                                                                 \
            val = (sizeof(REG) == 4) ? __LDREXW((volatile uint32_t *)&(REG)) | (BIT) : (sizeof(REG) == 2) ? __LDREXH((volatile uint16_t *)&(REG)) | (BIT) \
                                                                                                          : __LDREXB((volatile uint8_t *)&(REG)) | (BIT); \
        } while (                                                                                                                                         \
            ((sizeof(REG) == 4) ? __STREXW(val, (volatile uint32_t *)&(REG)) : (sizeof(REG) == 2) ? __STREXH(val, (volatile uint16_t *)&(REG))            \
                                                                                                  : __STREXB(val, (volatile uint8_t *)&(REG))) != 0U);    \
    } while (0)

/* 原子清位 */
#define ATOMIC_CLEAR(REG, BIT)                                                                                                                              \
    do                                                                                                                                                      \
    {                                                                                                                                                       \
        __CHECK_REG_SIZE(REG);                                                                                                                              \
        typeof(REG) val;                                                                                                                                    \
        do                                                                                                                                                  \
        {                                                                                                                                                   \
            val = (sizeof(REG) == 4) ? __LDREXW((volatile uint32_t *)&(REG)) & ~(BIT) : (sizeof(REG) == 2) ? __LDREXH((volatile uint16_t *)&(REG)) & ~(BIT) \
                                                                                                           : __LDREXB((volatile uint8_t *)&(REG)) & ~(BIT); \
        } while (                                                                                                                                           \
            ((sizeof(REG) == 4) ? __STREXW(val, (volatile uint32_t *)&(REG)) : (sizeof(REG) == 2) ? __STREXH(val, (volatile uint16_t *)&(REG))              \
                                                                                                  : __STREXB(val, (volatile uint8_t *)&(REG))) != 0U);      \
    } while (0)

/* 原子修改 */
#define ATOMIC_MODIFY(REG, CLEARMSK, SETMASK)                                                                                                                                                     \
    do                                                                                                                                                                                            \
    {                                                                                                                                                                                             \
        __CHECK_REG_SIZE(REG);                                                                                                                                                                    \
        typeof(REG) val;                                                                                                                                                                          \
        do                                                                                                                                                                                        \
        {                                                                                                                                                                                         \
            val = (sizeof(REG) == 4) ? (__LDREXW((volatile uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK) : (sizeof(REG) == 2) ? (__LDREXH((volatile uint16_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK) \
                                                                                                                              : (__LDREXB((volatile uint8_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
        } while (                                                                                                                                                                                 \
            ((sizeof(REG) == 4) ? __STREXW(val, (volatile uint32_t *)&(REG)) : (sizeof(REG) == 2) ? __STREXH(val, (volatile uint16_t *)&(REG))                                                    \
                                                                                                  : __STREXB(val, (volatile uint8_t *)&(REG))) != 0U);                                            \
    } while (0)

/* ------------------------- 原子加载 ------------------------- */
#define ATOMIC_LOAD(reg) ({                    \
    __CHECK_REG_SIZE(reg);                     \
    typeof(reg) oldval;                        \
    do                                         \
    {                                          \
        oldval = __LDREX_IMPL(reg);            \
    } while (__STREX_IMPL(reg, oldval) != 0U); \
    oldval;                                    \
})
/* ------------------------- 原子存储 ------------------------- */
#define ATOMIC_STORE(reg, newval)                    \
    do                                               \
    {                                                \
        __CHECK_REG_SIZE(reg);                       \
        typeof(reg) tmp;                             \
        do                                           \
        {                                            \
            tmp = __LDREX_IMPL(reg);                 \
        } while (__STREX_IMPL(reg, (newval)) != 0U); \
    } while (0)
/* ------------------------- 原子加 ------------------------- */
#define ATOMIC_ADD(reg, val) ({                        \
    __CHECK_REG_SIZE(reg);                             \
    typeof(reg) oldval;                                \
    do                                                 \
    {                                                  \
        oldval = __LDREX_IMPL(reg);                    \
    } while (__STREX_IMPL(reg, oldval + (val)) != 0U); \
    oldval;                                            \
})
/* ------------------------- 原子减 ------------------------- */
#define ATOMIC_SUB(reg, val) ({                        \
    __CHECK_REG_SIZE(reg);                             \
    typeof(reg) oldval;                                \
    do                                                 \
    {                                                  \
        oldval = __LDREX_IMPL(reg);                    \
    } while (__STREX_IMPL(reg, oldval - (val)) != 0U); \
    oldval;                                            \
})

/* ------------------------- 原子与 ------------------------- */
#define ATOMIC_AND(reg, mask) ({                        \
    __CHECK_REG_SIZE(reg);                              \
    typeof(reg) oldval;                                 \
    do                                                  \
    {                                                   \
        oldval = __LDREX_IMPL(reg);                     \
    } while (__STREX_IMPL(reg, oldval & (mask)) != 0U); \
    oldval;                                             \
})
/* ------------------------- 原子或 ------------------------- */
#define ATOMIC_OR(reg, mask) ({                         \
    __CHECK_REG_SIZE(reg);                              \
    typeof(reg) oldval;                                 \
    do                                                  \
    {                                                   \
        oldval = __LDREX_IMPL(reg);                     \
    } while (__STREX_IMPL(reg, oldval | (mask)) != 0U); \
    oldval;                                             \
})
/* ------------------------- 原子异或 ------------------------- */
#define ATOMIC_XOR(reg, mask) ({                        \
    __CHECK_REG_SIZE(reg);                              \
    typeof(reg) oldval;                                 \
    do                                                  \
    {                                                   \
        oldval = __LDREX_IMPL(reg);                     \
    } while (__STREX_IMPL(reg, oldval ^ (mask)) != 0U); \
    oldval;                                             \
})

/* ------------------------- 原子交换 ------------------------- */
#define ATOMIC_SWAP(reg, newval) ({              \
    __CHECK_REG_SIZE(reg);                       \
    typeof(reg) oldval;                          \
    do                                           \
    {                                            \
        oldval = __LDREX_IMPL(reg);              \
    } while (__STREX_IMPL(reg, (newval)) != 0U); \
    oldval;                                      \
})

/* ------------------------- 原子标志操作 ------------------------- */
#define ATOMIC_FLAG_CLEAR(reg)                \
    do                                        \
    {                                         \
        __CHECK_REG_SIZE(reg);                \
        typeof(reg) tmp;                      \
        do                                    \
        {                                     \
            tmp = __LDREX_IMPL(reg);          \
        } while (__STREX_IMPL(reg, 0) != 0U); \
    } while (0)

#define ATOMIC_FLAG_SET(val) ({                                                                                                            \
    typeof(val) oldval;                                                                                                                    \
    do                                                                                                                                     \
    {                                                                                                                                      \
        oldval = (sizeof(val) == 4) ? __LDREXW((volatile uint32_t *)&val) : (sizeof(val) == 2) ? __LDREXH((volatile uint16_t *)&val)       \
                                                                                               : __LDREXB((volatile uint8_t *)&val);       \
    } while (                                                                                                                              \
        ((sizeof(val) == 4) ? __STREXW(1, (volatile uint32_t *)&val) : (sizeof(val) == 2) ? __STREXH(1, (volatile uint16_t *)&val)         \
                                                                                          : __STREXB(1, (volatile uint8_t *)&val)) != 0U); \
    oldval;                                                                                                                                \
})

/* ------------------------- 原子比较交换 ------------------------- */
#define ATOMIC_COMPARE_EXCHANGE_STRONG(reg, old, new) ({ \
    __CHECK_REG_SIZE(reg);                               \
    typeof(reg) result, temp = *(old);                   \
    int success = 0;                                     \
    do                                                   \
    {                                                    \
        result = __LDREX_IMPL(reg);                      \
        if (result != temp)                              \
        {                                                \
            *(old) = result;                             \
            (void)__STREX_IMPL(reg, result);             \
            break;                                       \
        }                                                \
    } while (__STREX_IMPL(reg, (new)) != 0U);            \
    (result == temp);                                    \
})

#include <stdarg.h>
#define RT_SECTION(x) __attribute__((section(x)))
#define RT_UNUSED __attribute__((unused))
#define RT_USED __attribute__((used))
#define ALIGN(n) __attribute__((aligned(n)))
#define RT_WEAK __attribute__((weak))
#define rt_inline static __inline





#ifdef __cplusplus
}
#endif

#endif // PUBLIC_H